import React from 'react';
import {Select} from 'antd';;

const {Option, OptGroup} = Select;
/**
 * linkText,linkMethod  添加一个链接，点击则调用linkMethod方法<br/>
 * needAllOption, form, field,  列表添加一个All的选项，并且与其他选项进行互斥<br/>
 * classNameHandler, 根据value自定义显示样式<br/>
 * image: 图片，结构和传入的数据对应
 * @param props
 * @returns {*}
 * @constructor
 */
const Selector = (props)=>{
    let {hideAll, list=[], value,allText="",colorEnabled,showSearch, onChange,linkText,linkMethod,defaultValue, groupField,groupCms,needAllOption,form,formField,classNameHandler,getPopupContainer,image, ...rest} = props;
    let textCms = window.cms.PlainText;
    let popupContainerObj = getPopupContainer ? getPopupContainer :  triggerNode=> triggerNode.parentElement
    if(!hideAll && value==undefined){
        value="";
    }
    let className="";
    if(colorEnabled){
        if(classNameHandler){
            className= classNameHandler(value)
        }else{
            className = value ? "success" : "danger"
        }
    }

    if(!defaultValue){
        rest.value = value;
    }
    rest.defaultValue = defaultValue;
    if(showSearch==undefined && list.length>8){
        showSearch=true
    }
    if(rest.disabled || rest.readOnly){
        rest.tabIndex= "-1"
    }

    // 分组  groupField :指定分组的字段； groupCms :多语言支持
    let groupMap = [];
    if(groupField){
        let map = {};
        list.forEach(o=>{
            let k = o[groupField];
            if(!map[k]){
                map[k] = []
            }
            map[k].push({...o})
        })
        for(let k in map){
            let tmpList = map[k]
            groupMap.push(<OptGroup label={groupCms[k] || k}>
                {tmpList.map(o=><Option value={o.code} key={o.code} disabled={o.disabled} title={o.name}>{o.name}</Option>)}
            </OptGroup>)
        }
    }
    if(form && needAllOption && formField) {
        hideAll = true
    }
    const handleChange=(value)=>{
        if(form && needAllOption && formField){
            hideAll=true
            if(value.length>1 && value.includes("All")){
                // 先选all, 再选其他，则把All清空
                if(value[0]=="All"){
                    value.splice(0,1)
                }else{ // 先选其他, 再选ALL，则把其他清空
                    value = ["All"];
                }
                setTimeout(()=>{
                    form.setFieldsValue({[formField]: value})
                },100)
            }
        }
        onChange && onChange(value)
    }
    if(needAllOption){
        list = [{code:"All",name:textCms.all},...list]
    }


    return <Select onChange={handleChange} className={className} getPopupContainer={popupContainerObj}  showSearch={showSearch} {...rest}  >
        {hideAll || <Option value="">- {allText || textCms.all} -</Option>}
        {linkText && linkMethod && <Option value="LINK-OPTION" className="link-text" onClick={linkMethod}>{linkText}</Option>}

        {
            groupField
                ? groupMap
                : list.map(o=><Option value={o.code} key={o.code} disabled={o.disabled} className={o.className}  title={o.title||o.name}>{image?<img src={image[o.code]}/>:null} {o.name}</Option>)}
    </Select>
}

// 数组 ["a","b"]
const ListSelector = (props)=>{
    let {list,type, ...rest} = props;
    list = list || window.cms.Enum[type];
    let arr = list.map(o=>{return {code:o,name:o}})
    return <Selector  list={arr} {...rest}/>
}

// 对象数组，[{code:"a",name:"aa"}]
const ObjListSelector = (props)=>{
    let {list=[], cms, field="code", label="name",enableEnumType="Valid",extraEnumType="CustomerStatus",...rest} = props;

    let showEnabled = list[0] && list[0].hasOwnProperty("enabled");

    let enabledArr = window.cms.Enum[enableEnumType];
    let extraCms = window.cms.Enum[extraEnumType];
    let arr = list.map(o=>{
        let name = cms ? cms[o[label]] : o[label]
        if(showEnabled && !o.enabled){
            name = `(${enabledArr[1]}) ${name}`
        }
        // 类似enabled的效果，主要针对客户，显示不同的状态
        if(!showEnabled && o.labelExtra){
            name = `(${extraCms[o.labelExtra]}) ${name}`
        }
        return {...o,code:o[field],name}
    })

    return <Selector  list={arr} {...rest}/>
}
/**
 * map, {a:"a",b:"b"}
 * sort: 用于控制顺序，可选
 * isNumKey: true, 代表key为数字，按照数字大小来排序
 */
const MapSelector = (props)=>{
    let {data, type, sort,isNumKey,sortByLetter,  ...rest} = props;
    let arr = [];
    data = data || window.cms.Enum[type] || {};
    if(isNumKey){
        // key按照数字排序
        let keys = Object.keys(data);
        keys.sort((a1, a2)=>Number(a1) - Number(a2))
        sort = keys;
    }if(sortByLetter){  //依照首字母顺序 排序
        let values = Object.values(data),keys=[];
        values.sort((a,b)=> a.charCodeAt(0)-b.charCodeAt(0) )
        values.forEach(k=>{
            for(let t in data){
                if(data[t]==k) keys.push(t)
            }
        })
        sort = keys;
    }
    if(sort){
        sort.forEach(k=>{
            arr.push({code:k, name:data[k]})
        });
    }else{
        arr =Object.keys(data).map(o=>{return {code:o,name:data[o]}});
    }
    return <Selector  list={arr} {...rest}/>
}

const BooleanSelector = (props)=>{
    let {type,list, ...rest} = props;
    list = list || window.cms.Enum[type];
    let data=[
        {code:true, name:list[0]},
        {code:false, name:list[1]},
    ]
    return <Selector  list={data} {...rest}/>
}

const SearchInput = (props) => {
    let {value,showSearch,onSearch,onBlur,onChange,list,...rest} = props
    return <Select
        showSearch={showSearch}
        value={ value}
        onSearch={onSearch}
        onBlur={onBlur}
        onChange={onChange}   {...rest}
    >
        {list.map((o,i) => <Option  key={i}>{o}</Option>)}
    </Select>
}
export {ListSelector, ObjListSelector, MapSelector, BooleanSelector,Selector,SearchInput}